package com.raedev.forms.dialog;

import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.core.content.ContextCompat;

import androidx.appcompat.widget.LinearLayoutCompat;

import com.kongzue.dialogx.DialogX;
import com.kongzue.dialogx.dialogs.BottomDialog;
import com.kongzue.dialogx.dialogs.PopTip;
import com.kongzue.dialogx.interfaces.BaseDialog;
import com.kongzue.dialogx.interfaces.OnBindView;
import com.kongzue.dialogx.interfaces.OnDialogButtonClickListener;
import com.kongzue.dialogx.style.MaterialStyle;
import com.raedev.forms.R;
import com.raedev.forms.dialog.interfaces.OnCustomWheelPickerSelected;
import com.raedev.forms.dialog.interfaces.OnWheelChangeListener;
import com.raedev.forms.dialog.view.ArrayWheelAdapter;
import com.raedev.forms.dialog.view.OnWheelChangedListener;
import com.raedev.forms.dialog.view.WheelView;
import com.raedev.forms.dict.FormDataProvider;
import com.raedev.forms.dict.FormSelectItem;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author: Kongzue
 * @github: https://github.com/kongzue/
 * @homepage: http://kongzue.com/
 * @mail: myzcxhh@live.cn
 * @createTime: 2021/9/29 16:48
 */
public class CustomWheelPickerDialog {

    protected BottomDialog bottomDialog;
    protected List<FormSelectItem[]> wheelDataList;
    protected List<WheelView> wheelViewList;
    protected Map<Integer, Integer> defaultSelect;
    protected OnWheelChangeListener onWheelChangeListener;
    protected String title;

    private TextView txtDialogTitle;
    private LinearLayoutCompat boxWheel;
    private LinearLayoutCompat llSelected;
    private ArrayList<FormSelectItem> mCurrentSelectedItem;
    private FormDataProvider provider;
    private boolean selected;

    public static CustomWheelPickerDialog build() {
        return new CustomWheelPickerDialog();
    }

    private int px2dp(View view, int px) {
        int dp = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, px, view.getResources().getDisplayMetrics());
        return dp;
    }

    private void setSelectedViewColor() {
        for (int i = 0; i < llSelected.getChildCount(); i++) {
            View child = llSelected.getChildAt(i);
            if (child instanceof TextView) {
                if (i == llSelected.getChildCount() - 1) {
                    TextView lastTextView = (TextView) child;
                    lastTextView.setTextColor(llSelected.getResources().getColor(R.color.orange1));
                    lastTextView.setBackground(ContextCompat.getDrawable(llSelected.getContext(), R.drawable.round_bt_background));
                } else {
                    TextView otherView = (TextView) child;
                    otherView.setTextColor(llSelected.getResources().getColor(R.color.gray2));
                    otherView.setBackground(ContextCompat.getDrawable(llSelected.getContext(), R.drawable.def_bt_background));
                }
            }
        }
    }

    /**
     * 返回上一级
     */
    private List<FormSelectItem> backToThePreviousLevel(FormSelectItem item) {
        if (item == null || item.getParent() == null) {
            return provider.getItems(null);
        }
        // 获取祖父节点
        FormSelectItem parent = item.getParent().getParent();
        // 如果祖父节点不存在，设置根数据并返回
        if (parent == null) {
            return provider.getItems(null);
        }
        return parent.getChildren$forms_release();
    }

    private void setSelectedView(FormSelectItem text) {
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, px2dp(llSelected, 24));
        TextView textView = new TextView(llSelected.getContext());
        textView.setText(text.getLabel());
        textView.setTag(text.getValue());
        textView.setPadding(px2dp(textView, 5), px2dp(textView, 5), px2dp(textView, 5), px2dp(textView, 5));
        textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12);
        textView.setOnClickListener(v -> {
            FormSelectItem item = provider.getItem(textView.getTag().toString());

            List<FormSelectItem> items = this.backToThePreviousLevel(item);
//            List<FormSelectItem> items = provider.getItems(item);
//            List<FormSelectItem> items = provider.getItems(text);
            FormSelectItem[] itemsArray = items.toArray(new FormSelectItem[0]);
            setWheel(0, itemsArray);

            // 获取当前 TextView 的索引
            int clickedIndex = llSelected.indexOfChild(v);
            if (clickedIndex == -1) return;
            // 移除之后的所有子视图
            int childCount = llSelected.getChildCount();
            for (int i = childCount - 1; i >= clickedIndex; i--) {
                llSelected.removeViewAt(i);
                mCurrentSelectedItem.remove(i);
            }
            // 更新最后一个 TextView 的样式
            setSelectedViewColor();

        });
        textView.setAlpha(0f);
        llSelected.addView(textView, lp);
        textView.animate()
                .alpha(1f)
                .setDuration(300)
                .start();
        setSelectedViewColor();
    }

    public void okButton(OnCustomWheelPickerSelected onCustomWheelPickerSelected) {
        handleSelection(onCustomWheelPickerSelected);
    }

    public CustomWheelPickerDialog show(OnCustomWheelPickerSelected onCustomWheelPickerSelected) {
        bottomDialog = BottomDialog.show(new OnBindView<BottomDialog>(R.layout.dialogx_custom_wheel_picker) {
                    @Override
                    public void onBind(BottomDialog dialog, View v) {
                        bottomDialog = dialog;
                        txtDialogTitle = v.findViewById(R.id.txt_dialog_title);
                        boxWheel = v.findViewById(R.id.box_wheel);
                        llSelected = v.findViewById(R.id.ll_selected);
                        txtDialogTitle.setTextColor(dialog.getResources().getColor(dialog.isLightTheme() ? R.color.black : R.color.white));
                        txtDialogTitle.getPaint().setFakeBoldText(true);
                        if (title != null) txtDialogTitle.setText(title);
                        refreshUI();
                        for (int i = 0; i < wheelViewList.size(); i++) {
                            WheelView wheelView = wheelViewList.get(i);
                            if (defaultSelect != null) {
                                Integer selectIndex = defaultSelect.get(i);
                                if (selectIndex != null) {
                                    wheelView.setCurrentItem(selectIndex);
                                }
                            }
                        }
                        for (FormSelectItem item : mCurrentSelectedItem) {
                            setSelectedView(item);
                        }
                    }
                })
                .setCancelable(true)
                .setAllowInterceptTouch(false);

        if (DialogX.globalStyle instanceof MaterialStyle) {
            bottomDialog.setOkButton(R.string.dialogx_custom_wheel_picker_ok_button,
                            (baseDialog, v) -> handleSelection(onCustomWheelPickerSelected))
                    .setCancelButton(R.string.dialogx_custom_wheel_picker_dialog_cancel,
                            (baseDialog, v) -> {
                                onCustomWheelPickerSelected.onCancel();
                                return false;
                            });
        } else {
            bottomDialog.setCancelButton(R.string.dialogx_custom_wheel_picker_ok_button,
                    (baseDialog, v) -> handleSelection(onCustomWheelPickerSelected));
        }

        return this;
    }
    int[] selectedIndex = new int[1];
    // 新增统一处理方法
    private boolean handleSelection(OnCustomWheelPickerSelected callback) {

        FormSelectItem item = null;
        FormSelectItem[] selectedTexts = new FormSelectItem[wheelDataList.size()];


        if (wheelViewList == null || wheelViewList.isEmpty()) {
            callback.onSelected(CustomWheelPickerDialog.this, null, new FormSelectItem[]{}, new int[]{}, new ArrayList<>());
            return false;
        }

        for (int i = 0; i < wheelDataList.size(); i++) {
            item = getWheelSelected(i);
            if (!selected) {
                selected = true;
                selectedTexts[i] = item;
                selectedIndex[i] = getWheelSelectedIndex(i);
            }
        }

        if (item != null) {
            int currentLevel = getItemLevel(item);
            if (currentLevel >= 0 && currentLevel < mCurrentSelectedItem.size()) {
                mCurrentSelectedItem.subList(currentLevel, mCurrentSelectedItem.size()).clear();
            } else if (currentLevel >= 0) {
                setSelectedView(item);
            }
            mCurrentSelectedItem.add(item);
        }

        callback.onSelected(CustomWheelPickerDialog.this, item, selectedTexts, selectedIndex, mCurrentSelectedItem);

        return item != null && (item.getHasChildren$forms_release() || item.isNext());
    }

    private int getItemLevel(FormSelectItem item) {
        int level = 0;
        FormSelectItem parent = item.getParent();
        while (parent != null) {
            level++;
            parent = parent.getParent();
        }
        return level;
    }

    public CustomWheelPickerDialog setFormDataProvider(FormDataProvider provider) {
        this.provider = provider;
        return this;
    }

    public CustomWheelPickerDialog addWheel(FormSelectItem[] wheelList) {
        if (wheelDataList == null) {
            wheelDataList = new ArrayList<>();
        }
        wheelDataList.add(wheelList);
        refreshUI();
        return this;
    }

    public CustomWheelPickerDialog setWheel(int index, FormSelectItem[] wheelList) {
        if (wheelDataList == null) {
            wheelDataList = new ArrayList<>();
        }
        if (index >= wheelDataList.size()) {
            for (int i = wheelDataList.size(); i <= index; i++) {
                wheelDataList.add(new FormSelectItem[0]);
            }
        }
        wheelDataList.set(index, wheelList);
        refreshUI();
        return this;
    }

    public FormSelectItem[] getWheel(int index) {
        if (wheelDataList == null) {
            wheelDataList = new ArrayList<>();
        }
        if (index <= wheelDataList.size()) {
            for (int i = wheelDataList.size(); i <= index; i++) {
                wheelDataList.add(new FormSelectItem[0]);
            }
        }
        return wheelDataList.get(index);
    }

    public FormSelectItem getWheelSelected(int index) {
        if (wheelDataList == null) {
            wheelDataList = new ArrayList<>();
        }
        if (index <= wheelDataList.size()) {
            for (int i = wheelDataList.size(); i <= index; i++) {
                wheelDataList.add(new FormSelectItem[0]);
            }
        }
        return wheelDataList.get(index)[wheelViewList.get(index).getCurrentItem()];
    }

    public int getWheelSelectedIndex(int index) {
        if (wheelViewList == null) {
            wheelViewList = new ArrayList<>();
        }
        if (index >= wheelViewList.size()) return 0;
        return wheelViewList.get(index).getCurrentItem();
    }

    protected void refreshUI() {
        if (boxWheel != null) {
            if (mCurrentSelectedItem == null) {
                mCurrentSelectedItem = new ArrayList<>();
            }
            if (wheelViewList == null) {
                wheelViewList = new ArrayList<>();
            }
            if (wheelDataList == null) {
                wheelDataList = new ArrayList<>();
            }
            if (wheelViewList.size() != wheelDataList.size()) {
                if (wheelViewList.size() < wheelDataList.size()) {
                    for (int i = wheelViewList.size(); i < wheelDataList.size(); i++) {
                        WheelView wheelView = new WheelView(boxWheel.getContext());
                        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
                        lp.weight = 1;
                        wheelViewList.add(wheelView);
                        boxWheel.addView(wheelView, lp);
                    }
                } else {
                    for (int i = wheelViewList.size() - 1; i >= wheelDataList.size(); i--) {
                        boxWheel.removeView(wheelViewList.get(i));
                    }
                }
            }
            for (WheelView wheelView : wheelViewList) {
                ArrayWheelAdapter<FormSelectItem> customAdapter = new ArrayWheelAdapter<>(BottomDialog.getTopActivity(),
                        Arrays.asList(wheelDataList.get(wheelViewList.indexOf(wheelView))));
                customAdapter.setItemResource(R.layout.default_item_custom_wheel);
                customAdapter.setItemTextResource(R.id.default_item_date_name_tv);
                customAdapter.setTextColor(bottomDialog.getResources().getColor(bottomDialog.isLightTheme() ? R.color.black60 : R.color.white70));
                wheelView.setViewAdapter(customAdapter);

                wheelView.setChangingListener(new OnWheelChangedListener() {
                    @Override
                    public void onChanged(WheelView wheel, int oldValue, int newValue) {
                        if (getOnWheelChangeListener() != null) {
                            getOnWheelChangeListener().onWheel(CustomWheelPickerDialog.this,
                                    wheelViewList.indexOf(wheelView),
                                    wheelDataList.get(wheelViewList.indexOf(wheelView)),
                                    newValue, wheelDataList.get(wheelViewList.indexOf(wheelView))[newValue]
                            );
                        }
                    }
                });
            }
        }
    }

    public OnWheelChangeListener getOnWheelChangeListener() {
        return onWheelChangeListener;
    }

    public CustomWheelPickerDialog setOnWheelChangeListener(OnWheelChangeListener onWheelChangeListener) {
        this.onWheelChangeListener = onWheelChangeListener;
        return this;
    }

    public CustomWheelPickerDialog setDefaultSelect(Map<Integer, Integer> defaultSelect) {
        this.defaultSelect = defaultSelect;
        if (wheelViewList != null) {
            Set<Integer> keySet = defaultSelect.keySet();
            for (Integer key : keySet) {
                if (key < wheelViewList.size()) {
                    int selection = defaultSelect.get(key);
                    wheelViewList.get(key).setCurrentItem(selection);
                }
            }
        }
        return this;
    }

    public CustomWheelPickerDialog setDefaultSelectedItems(ArrayList<FormSelectItem> currentSelectedItem) {
        this.mCurrentSelectedItem = currentSelectedItem;

        return this;
    }

    public CustomWheelPickerDialog setDefaultSelect(int wheelIndex, int selectItemIndex) {
        if (defaultSelect == null) {
            defaultSelect = new HashMap<>();
        }
        defaultSelect.put(wheelIndex, selectItemIndex);
        if (wheelViewList != null) {
            Set<Integer> keySet = defaultSelect.keySet();
            for (Integer key : keySet) {
                if (key < wheelViewList.size()) {
                    int selection = defaultSelect.get(key);
                    wheelViewList.get(key).setCurrentItem(selection);
                }
            }
        }
        return this;
    }

    public CustomWheelPickerDialog setTitle(String title) {
        this.title = title;
        if (txtDialogTitle != null) {
            txtDialogTitle.setText(title);
        }
        return this;
    }

    public CustomWheelPickerDialog setTitle(int resId) {
        this.title = BaseDialog.getTopActivity().getString(resId);
        if (txtDialogTitle != null) {
            txtDialogTitle.setText(title);
        }
        return this;
    }

    public BottomDialog getDialog() {
        return bottomDialog;
    }
}
